<?php

	include_once 'DBConnection.php';
	include_once 'Post.php';
	include_once 'Posts.php';
	include_once 'model/User.php';
	include_once 'model/UserDAO.php';

class PostDAO {
	private static $instance;
	
	private function __construct() {
		
	}
	
	public static function getInstance() {
		if (!isset(self::$instance)) {
			$className = __CLASS__;
			self::$instance = new $className;
		}
		return self::$instance;
	}
	
	public function getOwnersPostById($id) {
	$post=new Post();
	$db=DBConnection::getInstance();		
		$res=null;
		if ($db instanceof  DBConnection) {			
			try {
				$res=$db->exec_select_query(Post::getPostByIdStatement(),array($id));
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage().'<br />';
			}
			if (!isset($res) || empty($res)) return null;
			$post->setOwnerId($res[0]["user_id"]);			
			return $post;
		}
	}
	
	public function getOriginalPostIdtByPostId($postId) {
		$db=DBConnection::getInstance();		
		$res=null;
		if ($db instanceof  DBConnection) {			
			try {
				$res=$db->exec_select_query(Post::getPostByIdStatement(),array($postId));					
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage().'<br />';
			}
			if (!isset($res) || empty($res)) return false;
			if (isset($res[0]["post_content_id"])) {				
				return $postId;
			}			
			if (isset($res[0]["repost_id"])) {				
				try {
				$rep=$db->exec_select_query(Post::getRepostByIdStatement(),array($res[0]["repost_id"]));				
				} catch (PDOException $e) {
					echo "Error: ".$e->getMessage().'<br />';
				}	
				return $rep[0]["original_post_id"];
			} 
			return $postId;
		}
	}
	
	public function getPosts($userId, $displayLevel, $beginPostID, $count) {
		$post=new Post();
		$db=DBConnection::getInstance();
		$result_simple_posts = null;
		$result_reposts_from_user = null;
		$result_repost_by_user = null;
		
		if ($beginPostID == -1 && $userId > 0) {
			
			try {
				$result_simple_posts=$db->exec_select_query($post->getNLatestPostsForUser(),array($userId),$count);
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage().'<br />';
			}
			
			try {
				$result_repost_by_user=$db->exec_select_query($post->getRepostsByUserStatement(),array($userId));
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage().'<br />';
			}
			
			list($posts_list, $maxId)=$this->fillPostObjects($result_simple_posts,$result_repost_by_user);
			//$this->sortBydate($posts_list);
			$toReturn = new Posts();
			$toReturn->setUser($userId);
			$toReturn->setPosts($posts_list);
			$toReturn->setMaxId($maxId);
			return $toReturn;
		}
		
		if ($userId==-1 && $beginPostID>0) {
			try {
				$result_simple_posts=$db->exec_select_query($post->getNPostsBeforeDate(),array($beginPostID),$count);
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage().'<br />';
			}
			
			list($posts_list, $maxId)=$this->fillPostObjects($result_simple_posts);
		
			$toReturn=new Posts();
			$toReturn->setUser($userId);
			$toReturn->setPosts($posts_list);
			$toReturn->setMaxId($maxId);
			
			return $toReturn;
		}
		
		if ($userId==-1 && $beginPostID==-1) {
			try {
				$result_simple_posts=$db->exec_select_query($post->getAllPostsStatement(),array(),$count);
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage().'<br />';
			}
			
			try{
				$result_repost_by_user=$db->exec_select_query($post->getNReposts(),array(),$count);
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage().'<br />';
			}
			
			list($posts_list, $maxId)=$this->fillPostObjects($result_simple_posts,$result_repost_by_user);
					
			$toReturn=new Posts();
			$toReturn->setUser($userId);
			$toReturn->setPosts($posts_list);
			$toReturn->setMaxId($maxId);
			return $toReturn;
		}
		
		try {
			$result_simple_posts=$db->exec_select_query($post->getPostsStatement(),array($beginPostID,$userId),$count);
		} catch (PDOException $e) {
			echo "Error: ".$e->getMessage().'<br />';
		}
		
		try {
			$result_reposts_from_user=$db->exec_select_query($post->getRepostsStatement(),array($userId));
		} catch (PDOException $e) {
			echo "Error: ".$e->getMessage().'<br />';
		}
		
		try {
			$result_repost_by_user=$db->exec_select_query($post->getRepostsByUserStatement(),array($userId));
		} catch (PDOException $e) {
			echo "Error: ".$e->getMessage().'<br />';
		}
		
		list($posts_list, $maxId)=$this->fillPostObjects($result_simple_posts,$result_repost_by_user);
		
		$toReturn=new Posts();
		$toReturn->setUser($userId);
		$toReturn->setPosts($posts_list);
		$toReturn->setMaxId($maxId);
	
		return $toReturn;
	}
	
	private function fillPostObjects ($postFromDB, $repostByUser=null, $repostForUser=null) {
		$posts_list=null;
		$maxId = 0;		
		foreach ($postFromDB as $simple_post) {
			$sp=new Post();
			if (!isset($simple_post["content"])) {
				continue;
			} 
			$sp->setContent($simple_post["content"]);
			$sp->setOwnerId($simple_post["user_id"]);
			$sp->setId($simple_post["post_id"]);		
			$sp->setOriginalPostId($sp->getId());
			$sp->setTitle($simple_post["title"]);	
			$sp->setShowTitle($simple_post["show_title"]);
			$sp->setType($simple_post["name"]);
			$sp->setDate($simple_post["posted"]);
			$sp->setIsAuthor($simple_post["is_author"]);
			$sp->setSource($simple_post["source"]);		
			$sp->setDescription($simple_post["description"]);
			$sp->setTags($this->getTagsByPostId($sp->getId()));
			$sp->setListOfReposts($this->getRepostsForPost($sp->getId()));				
			$posts_list[$sp->getId()]=$sp;	
			if($sp->getId()>$maxId)
				$maxId = $sp->getId();
		}
		
		if (!isset($repostByUser))
			return $posts_list;
		foreach ($repostByUser as $r) {
			$sp=new Post();
			$sp->setId($r["post_id"]);
			$sp->setOwnerId($r["user_id"]);
			$prevuid=$r["prev_post_id"];
			if (isset($prevuid)) {
				$sp->setprevPostOwner($this->getOwnersPostById($r["prev_post_id"])->getOwnerId());
			}
			$sp->setOriginalPostOwner($this->getOwnersPostById($r["original_post_id"])->getOwnerId());			
			$sp->setContent($r["content"]);
			$sp->setIsRepost(true);
			$sp->setOriginalPostId($r["original_post_id"]);
			$sp->setIsAuthor(false);
			$sp->setDate($r["posted"]);
			$sp->setSource($r["source"]);
			$sp->setType($r["name"]);
			$sp->setTitle($r["title"]);
			$sp->setShowTitle($r["show_title"]);
			$sp->setDescription($r["description"]);
			$sp->setListOfReposts($this->getRepostsForPost($sp->getId()));
			$sp->setImage($r["image"]);				
			$sp->setTags($this->getTagsByPostId($sp->getId()));					
			$posts_list[$sp->getId()]=$sp;		
			if($sp->getId()>$maxId)
				$maxId = $sp->getId();
		}
		
		return array($posts_list, $maxId);
	}
	
	public function getRepostsForPost($id) {
		$db=DBConnection::getInstance();
		$list=null;		
		if ($db instanceof DBConnection) {
			try {								
				$res=$db->exec_select_query(Post::getGetRepostsForPostStatement(), array($id));				
				if (isset($res)) {					
					$i=0;
					foreach($res as $r) {											
						$list[$i++]=UserDAO::getInstance()->getUserById($r["user_id"]);
					}
				}				
			} catch (PDOException $e) {
				echo 'Error '.$e->getMessage().'<br />';
			}
		}
		return $list;
	}
	
	public function addSimplePost($userId,$post_content_id,$repost_id) {
		$db=DBConnection::getInstance();					
			$PId=$this->getCountPosts();
			$PId++;
			if ($db instanceof DBConnection) {
				try {
					$db->exec_param_transaction(Post::getAddPostStatement(),array($PId, $userId, 
					$post_content_id, $repost_id));
				} catch (PDOException $e) {
					echo "Error: ".$e->getMessage()."<br />";
				}			
			}				
		return true;
	}
	
	public function addPost($post,$userId) {		
		$PCId=$this->getCountPostsContent();
		$PId=$this->getCountPosts();		
		if ($post instanceof Post) {
			$db_conn=DBConnection::getInstance();
			$params = array(
				++$PCId, $this->getTypeId($post->getType()), $post->getContent(), $post->getDescription(),
				$post->getSource(), $post->getTitle(), $post->getShowTitle(), $post->isAuthor(),
				$post->getImage()
			);
			$db_conn->exec_param_transaction($post->getAddPostContentStatement(), $params);
			
			$params=array(++$PId, $userId, $PCId, NULL);
			$db_conn->exec_param_transaction($post->getAddPostStatement(), $params);
			
			$this->addTagsForPost($post->getTags(), $PId);
		}
	}
	
	public function getTypeId($typeName) {
		$db=DBConnection::getInstance();
		$id=-1;
		if ($db instanceof DBConnection) {
			try {								
				$res=$db->exec_select_query(Post::getTypeIdstatement(), array($typeName));
				if (isset($res[0]["type"]))
				 $id=$res[0]["type"];
			} catch (PDOException $e) {
			}
		}
		return $id;		
	}
	
	//, 10, $userId, 7, NULL
	public function getCountPostsContent() {
		return DBConnection::getInstance()->exec_count_select("SELECT * FROM post_content");
	}
	
	public function getCountPosts() {
		return DBConnection::getInstance()->exec_count_select("SELECT * FROM post");
	}
	
	public function getTagsByPostId($postId) {
		$db=DBConnection::getInstance();
		$toReturn=null;
		if ($db instanceof DBConnection) {
			try{
			$result=$db->exec_select_query(Post::getTagsStatement(), array($postId));
			}catch(PDOException $e) {
				echo "Error: ".$e->getMessage()."<br />";
			}
			$i=0;
			foreach($result as $r) {
				$toReturn[$i++]=$r["tag_content"];
			} 
		}
		return $toReturn;		
	}
	
	public function addTag($content) {
		$db=DBConnection::getInstance();		
		if ($db instanceof DBConnection) {		
			try {
				$tags=$db->exec_select_query(Post::getTagByContentStatement(),array($content));
				if (!empty($tags)) return false;
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage()."<br />";
				return false;
			}
			try{
				$tagId=$db->exec_count_select("SELECT * FROM tag");
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage()."<br />";
				return false;
			}
			$tagId++;
			
			try {
				$db->exec_param_transaction(Post::getAddTagStatement(),array($tagId,$content));
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage()."<br />";
				return false;				
			}
						
		}
		return true;
	}
	
	public function addTagsForPost($tags,$postId) {
		$db=DBConnection::getInstance();
		$i=0;
		if ($db instanceof DBConnection) {
			$tagId=$db->exec_count_select("SELECT * FROM tag");
			$tagId++;
			$tagsId=$db->exec_count_select("SELECT * FROM tags");
			$tagsId++;
			foreach ($tags as $t) {				
				if ($this->addTag($t)) {					
					try {
						$db->exec_param_transaction(Post::getAddTagForPostStatement(),array($postId,$tagId));
						$tagId++;
						$i++;
					} catch (PDOException $e) {
						echo "Error: ".$e->getMessage()."<br />";
						return false;	
					}
				}else {
					try {												
						$db->exec_param_transaction(Post::getAddTagForPostStatement(),array($postId,$this->getTagId($t)));												
					} catch (PDOException $e) {
						echo "Error: ".$e->getMessage()."<br />";
						return false;	
					}
				}
			}
		}

		return $i;
	}
	
	public function getTagId($content) {
		$db = DBConnection::getInstance();
		if ($db instanceof DBConnection) {
			try {				
				$res=$db->exec_select_query(Post::getTagIdStatement(),array($content));
				if (!isset($res)) return null;
				else return $res[0]["id"];
			} catch (PDOException $e) {
				echo "Error: ".$e->getMessage()."<br />";
			}
		}
	}

	//zwraca true jesli usunieto jakis post
	public function deletePost($postId) {
		$db = DBConnection::getInstance();
		if ($db instanceof DBConnection) {
			try {						
				$res = $db->exec_query(Post::getDeletePostStatement(), array($postId));  //exec_param_transaction
			} catch (PDOException $e) {
				echo $e->getMessage();
			}
		}
		return $res ? true : false;
	}
	
	public function addPostWithContent($post, $userId) {
		if(!($post instanceof Post))
			return null;
		$db = DBConnection::getInstance();
		if ($db instanceof DBConnection) {
			$dbh = $db->getDBH();
			try {			
				$dbh->beginTransaction();			
				$stmt = $dbh->prepare(
					'INSERT INTO post_content VALUES(DEFAULT, (
						SELECT type FROM type WHERE type.name=?
					), ?, ?, ?, ?, ?, ?, ?)'
				);
				$stmt->execute(
					array($post->getType(), $post->getContent(), $post->getDescription(), $post->getSource(), $post->getTitle(), 
					(int)$post->getShowTitle(), (int)$post->isAuthor(), $post->getImage())
				);
				$stmt = $dbh->prepare(
					'INSERT INTO post VALUES(DEFAULT, ?, LAST_INSERT_ID(), NULL, DEFAULT)'
				);
				$stmt->execute(	array($userId) );
				$postId = $dbh->lastInsertId();
				foreach($post->getTags() as $tag) {
					$stmt = $dbh->prepare('SELECT COUNT(*) FROM tag WHERE tag.tag_content=?');
					$stmt->execute(array($tag));
					$res = $stmt->fetch();
					if(!$res[0]) {
						$stmt = $dbh->prepare('INSERT INTO tag VALUES (DEFAULT, ?)');
						$stmt->execute(array($tag));
					}
					$stmt = $dbh->prepare('INSERT INTO tags VALUES (?, (
						SELECT id FROM tag WHERE tag.tag_content=?
					))');
					$stmt->execute(array($postId, $tag));
				}
				$dbh->commit();	
				/*$res = $db->exec_queries_in_transaction(Post::getAddPostWithContentStatement(), 
					array(
						array($post->getType(), $post->getContent(), $post->getDescription(), $post->getSource(), $post->getTitle(), 
						(int)$post->getShowTitle(), (int)$post->isAuthor(), $post->getImage()),
						array($userId)
					)
				);*/
			} catch (PDOException $e) {
				$dbh->rollback();
				echo $e->getMessage();
			}
		}
	}
	
	public function modifyPost($postId, $post) {
		if(!($post instanceof Post))
			return null;
		$db = DBConnection::getInstance();
		if ($db instanceof DBConnection) {
			$dbh = $db->getDBH();
			try {			
				$dbh->beginTransaction();			
				$stmt = $dbh->prepare(
					'INSERT IGNORE INTO post_content VALUES(DEFAULT, (
						SELECT type FROM type WHERE type.name=?
					), ?, ?, ?, ?, ?, ?, ?)'
				);
				$stmt->execute(
					array($post->getType(), $post->getContent(), $post->getDescription(), $post->getSource(), $post->getTitle(), 
					(int)$post->getShowTitle(), (int)$post->isAuthor(), $post->getImage())
				);
				$dbh->commit();	
			} catch (PDOException $e) {
				$dbh->rollback();
				echo $e->getMessage();
			}
		}
	}
}

?>